﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Controls;
using System.Windows.Media.Media3D;
using System.ComponentModel;

namespace Sinacor.Infra.UI.Controls.SmartClient
{
	public abstract class DrillDown : Viewport3D
	{
		/// <summary>
		/// Movimenta os elementos para frente(em relação à visão da camera)
		/// </summary>
		protected void MoveElementsForward()
		{
			int TotalItems = this.Children.Count - 1;
			for (int i = TotalItems; i >= 1; i--)
			{
				if (i == 1)
					DrillDownAnimation.MoveTopElementForward(this.Children[TotalItems] as Viewport2DVisual3D, this.Children[i] as Viewport2DVisual3D);
				else
					DrillDownAnimation.MoveRemainingElementsForward(this.Children[i - 1] as Viewport2DVisual3D, this.Children[i] as Viewport2DVisual3D);
			}
		}

		/// <summary>
		/// Movimenta os elementos para trás(em relação à visão da camera)
		/// </summary>
		/// <param name="translate">Posição do último elemento que será removido</param>
		protected void MoveElementsBackwards(TranslateTransform3D translate)
		{
			int TotalItems = this.Children.Count - 1;
			for (int i = TotalItems; i >= 1; i--)
			{
				if (i == TotalItems)
					DrillDownAnimation.MoveElementToParentPosition(translate, this.Children[i] as Viewport2DVisual3D, TotalItems == 1);
				else
					DrillDownAnimation.MoveElementsBackwards(translate, this.Children[i] as Viewport2DVisual3D, TotalItems - i, i == 1);
			}
		}

		/// <summary>
		/// Movimento o primeiro o elemento fazendo-o seguir a posição do cursor do mouse
		/// </summary>
		/// <param name="windowXSize">Tamanho total do eixo X da tela</param>
		/// <param name="windowYSize">Tamanho total do eixo Y da tela</param>
		/// <param name="mouseX">Posição do eixo X do mouse</param>
		/// <param name="mouseY">Posição do eixo Y do mouse</param>
		/// <param name="xStartPosition">Parametro de saída que recebe a posição no eixo X para saber onde o objeto foi deixado</param>
		/// <param name="yStartPosition">Parametro de saída que recebe a posição no eixo Y para saber onde o objeto foi deixado</param>
		protected void MoveElementFollowMouse(double windowXSize, double windowYSize, double mouseX, double mouseY, out double xStartPosition, out double yStartPosition)
		{
			ScaleTransform3D scale = ((ScaleTransform3D)((Transform3DGroup)this.Children[1].Transform).Children[1]);

			double maxViewPortXSize = (1 / scale.ScaleX) - 1.1;
			double maxMouseXSize = windowXSize;

			double maxViewPortYSize = (1 / scale.ScaleY) - 1;
			double maxMouseYSize = windowYSize;

			double offsetXResult = +((((2 * maxViewPortXSize) / maxMouseXSize) * (mouseX - 3)) - maxViewPortXSize);
			double offsetYResult = -((((2 * maxViewPortYSize) / maxMouseYSize) * (mouseY - 3)) - maxViewPortYSize + 0.95);

			xStartPosition = offsetXResult;
			yStartPosition = offsetYResult;

			if (((TranslateTransform3D)((Transform3DGroup)this.Children[1].Transform).Children[0]).HasAnimatedProperties)
				DrillDownAnimation.CleanAnimationProperties();

			((TranslateTransform3D)((Transform3DGroup)this.Children[1].Transform).Children[0]).SetValue(TranslateTransform3D.OffsetXProperty, offsetXResult);
			((TranslateTransform3D)((Transform3DGroup)this.Children[1].Transform).Children[0]).SetValue(TranslateTransform3D.OffsetYProperty, offsetYResult);
		}

		/// <summary>
		/// "Docka" o elemento a esquerda
		/// </summary>
		protected void DockToLeft()
		{
			DrillDownAnimation.MoveElementToLeftBoundary(this.Children[this.Children.Count - 1] as Viewport2DVisual3D);
		}

		/// <summary>
		/// "Docka" o elemento a esquerda
		/// </summary>
		protected void DockToRight()
		{
			DrillDownAnimation.MoveElementToRightBoundary(this.Children[this.Children.Count - 1] as Viewport2DVisual3D);
		}

		/// <summary>
		/// Retira o elemento principal do "dock" e envia o mesmo para a posição onde foi deixado anteriormente
		/// </summary>
		/// <param name="offsetX">Posição do eixo X para o onde o elemento deve ir</param>
		/// <param name="offsetY">Posição do eixo Y para o onde o elemento deve ir</param>
		protected void UnDock(double offsetX, double offsetY)
		{
			DrillDownAnimation.MoveElementToDesiredStartPosition(this.Children[1] as Viewport2DVisual3D, offsetX, offsetY, 100);
		}

		/// <summary>
		/// Muda o estilo dos itens do menu
		/// </summary>
		protected void SetFadeVisibilityToItem()
		{
			int TotalItems = this.Children.Count - 1;
			for (int i = 1; i <= TotalItems; i++)
			{
				if (i == TotalItems)
					((SinacorMenu)((Viewport2DVisual3D)this.Children[i]).Visual).MenuOpacity = 1;
				else
					((SinacorMenu)((Viewport2DVisual3D)this.Children[i]).Visual).MenuOpacity = 0.7;
			}
		}
	}
}